//////////////////////////////////////////////////////////////////////////
// Track.h
//
// This class is responsible for configuring and rendering the race track
// used in the Genetics Presentation. It will allow the user to interface
// with the Bezier Spline class to change track layout etc.
//
// Created: 27/4/11
// By Matt Millwood
//////////////////////////////////////////////////////////////////////////

#ifndef TRACK_H
#define TRACK_H

#include <vector>
#include "Spline.h"

//////////////////////////////////////////////////////////////////////////
// Forward declarations.
//////////////////////////////////////////////////////////////////////////
class Entity;
class hgeSprite;
static float global_hack_pos;

//////////////////////////////////////////////////////////////////////////
// Racer struct. To be used for each racer, and two to be used when in
// render mode.
//////////////////////////////////////////////////////////////////////////
struct Racer
{
  Entity* pEntity;      // The genetics we possess.
  vector2f currPos;     // Current position in world coordinates.
  float currAngle;      // Radians, 0.0 is up.
  vector2f currVel;     // Current velocity.
  unsigned int section; // Section of the map we're up to.
};

class Track
{
public:
	Track();
	~Track();

  //////////////////////////////////////////////////////////////////////////
  // Initialize the track and racers.
  //////////////////////////////////////////////////////////////////////////
  void Init();

  //////////////////////////////////////////////////////////////////////////
  // Update the racers.
  //////////////////////////////////////////////////////////////////////////
	void Update(float a_dt);

	bool HasRaceFinished() const;

  //////////////////////////////////////////////////////////////////////////
  // Runs a lap for an entity.
  // @param[in] - Entity to run a lap for.
  //////////////////////////////////////////////////////////////////////////
	void RunLap(Entity* a_pEntity);

  //////////////////////////////////////////////////////////////////////////
  // Run a lap while rendering.
  // @param[in] - Father entity.
  // @param[in] - Mother entity.
  //////////////////////////////////////////////////////////////////////////
  void RunLapRender(Entity* a_pEntity);

  //////////////////////////////////////////////////////////////////////////
  // Render the track.
  //////////////////////////////////////////////////////////////////////////
  void RenderTrack();

  //////////////////////////////////////////////////////////////////////////
  // Whether we should render the spline.
  //////////////////////////////////////////////////////////////////////////
  void SetRenderSpline(bool a_state) { m_splineRender = a_state; }

	void ResetShit();
	float GetNeedlePos() const { return m_needlePos; }

private:
  Spline2D m_spline;                 // Spline used for race track.
  vector2f m_startPos;               // Starting position of spline racers.
  std::vector<vector2f> m_sections;  // Section start points for whole track.
  std::vector<vector2f> m_subSects;  // Sub sections, 10 per section.

  Racer m_father;                    // Father racer. Also used as default when not rendering.
  //Racer m_mother;                    // Mother racer. Used when rendering is required.

  hgeSprite* m_pTrackBack;           // Background for the track.
  hgeSprite* m_pTrackSection;        // Sprite to mark each section of the track.
  hgeSprite* m_pCarMother;		     // Mother car drawable.
  hgeSprite* m_pCarFather;			 // Father Car.
 
  bool m_renderMode;                 // Flag for if we're rendering (delta timed) or just
                                     // running evolutions (full speed).

  float m_avgSectionLength;          // The average length of each section.
  float m_maxSpeed;                  // Maximum speed of a racer.
  float m_carWidth;                  // Width of car for off track checks.

  bool m_hasFinished;                // Flag whether a lap is done.
  bool m_hasRaceFinished;

  bool m_fatherFinish;
  bool m_splineRender;                // Whether we should render the spline.

  float m_delta;                     // The last delta time. We'll need it.
  float m_needlePos;
};

#endif //TRACK_H